`ifndef ID_EX_V
`define ID_EX_V


`include "defines.v"

module id_ex(
    input  wire                         clk             ,
    input  wire                         rstn            ,

    // from id
    input  wire[`InstAddrWidth - 1 : 0] inst_addr_i     ,   // 指令地址传递
    input  wire[`InstWidth - 1 : 0]     inst_i          ,   // 指令传递
    input  wire[`RegAddrWidth - 1 : 0]  reg_waddr_i     ,   // 回写地址
    input  wire                         reg_wen_i       ,   // 回写使能
    input  wire[`RegDataWidth - 1 : 0]  reg1_rdata_i    ,   // 寄存器 1 值传递
    input  wire[`RegDataWidth - 1 : 0]  reg2_rdata_i    ,   // 寄存器 2 值传递
    input  wire[`OPWidth - 1 : 0]       op1_i           ,   // 操作数 1
    input  wire[`OPWidth - 1 : 0]       op2_i           ,   // 操作数 2
    
    // to ex
    output wire[`InstAddrWidth - 1 : 0] inst_addr_o     ,   // 指令地址传递
    output wire[`InstWidth - 1 : 0]     inst_o          ,   // 指令传递
    output wire[`RegAddrWidth - 1 : 0]  reg_waddr_o     ,   // 回写地址
    output wire                         reg_wen_o       ,   // 回写使能
    output wire[`RegDataWidth - 1 : 0]  reg1_rdata_o    ,   // 寄存器 1 值传递
    output wire[`RegDataWidth - 1 : 0]  reg2_rdata_o    ,   // 寄存器 2 值传递
    output wire[`OPWidth - 1 : 0]       op1_o           ,   // 操作数 1
    output wire[`OPWidth - 1 : 0]       op2_o               // 操作数 2
);

// 指令地址传递
pipe_dff #(32) inst_addr_dff(
    .clk        (clk)               ,		
    .rstn	    (rstn)              ,
    .hold_en	(1'b0)              ,
    .def_data   (`INST_ZERO_ADDR)   ,
    .data_i     (inst_addr_i)       ,
    .data_o	    (inst_addr_o)
);

// 指令传递
pipe_dff #(32) inst_dff(
    .clk        (clk)       ,		
    .rstn	    (rstn)      ,
    .hold_en	(1'b0)      ,
    .def_data   (`INST_NOP) ,
    .data_i     (inst_i)    ,
    .data_o	    (inst_o)
);

// 回写地址传递
pipe_dff #(5) reg_waddr_dff(
    .clk        (clk)           ,		
    .rstn	    (rstn)          ,
    .hold_en	(1'b0)          ,
    .def_data   (`R_X0_ADDR)    ,
    .data_i     (reg_waddr_i)   ,
    .data_o	    (reg_waddr_o)
);

// 回写使能传递
pipe_dff #(1) reg_wen_dff(
    .clk        (clk)       ,		
    .rstn	    (rstn)      ,
    .hold_en	(1'b0)      ,
    .def_data   (1'b0)      ,
    .data_i     (reg_wen_i) ,
    .data_o	    (reg_wen_o)
);

// 寄存器值 1 传递
pipe_dff #(32) reg1_rdata_dff(
    .clk        (clk)           ,		
    .rstn	    (rstn)          ,
    .hold_en	(1'b0)          ,
    .def_data   (`R_X0_DATA)    ,
    .data_i     (reg1_rdata_i)  ,
    .data_o	    (reg1_rdata_o)
);

// 寄存器值 2 传递
pipe_dff #(32) regw_rdata_dff(
    .clk        (clk)           ,		
    .rstn	    (rstn)          ,
    .hold_en	(1'b0)          ,
    .def_data   (`R_X0_DATA)    ,
    .data_i     (reg2_rdata_i)  ,
    .data_o	    (reg2_rdata_o)
);

// 操作数 1 传递
pipe_dff #(32) op1_dff(
    .clk        (clk)       ,		
    .rstn	    (rstn)      ,
    .hold_en	(1'b0)      ,
    .def_data   (`OP_ZERO)  ,
    .data_i     (op1_i)     ,
    .data_o	    (op1_o)
);

// 操作数 2 传递
pipe_dff #(32) op2_dff(
    .clk        (clk)       ,		
    .rstn	    (rstn)      ,
    .hold_en	(1'b0)      ,
    .def_data   (`OP_ZERO)  ,
    .data_i     (op2_i)     ,
    .data_o	    (op2_o)
);

endmodule

`endif // ID_EX_V